﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using FXSStation.Modules.SharedInfrastructureModule.Events;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Accounts;
using Microsoft.Practices.Composite.Presentation.Events;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Regions;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Orders;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Chart;
using System.ComponentModel;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Common;
using FXSStation.Modules.SharedInfrastructureModule.BusinessClasses.Currency;
using FXSStation.Modules.SharedInfrastructureModule.Extentions.TileView;
using UIComposition.Infrastructure;
using System.IO;

namespace FXSStation.Modules.DataModule.AccountView
{
    /// <summary>
    /// Interaction logic for AccountView.xaml
    /// </summary>
    public partial class AccountView : UserControl, INotifyPropertyChanged, IAccountView, ITileViewItem
    {
        public AccountView()
        {
            InitializeComponent();
            this.Title = "Account View";
            FileInfo fi = new FileInfo(RXSStationFileNames.ImagesPath + "Data.png");
            if (fi.Exists)
            {
                this.Icon = new BitmapImage(new Uri(fi.FullName, UriKind.RelativeOrAbsolute));
            }
        }
        public AccountView(IEventAggregator eventAggregator, IRegionManager regionManager)
            : this()
        {

            _eventAggregator = eventAggregator;

            // Subscribing for events :

            BuyOrderMadeEvent buyOrderMadeEvent = _eventAggregator.GetEvent<BuyOrderMadeEvent>();
            SellOrderMadeEvent sellOrderMadeEvent = _eventAggregator.GetEvent<SellOrderMadeEvent>();
            TickElapsedEvent tickElapsedEvent = _eventAggregator.GetEvent<TickElapsedEvent>();
            SimulationStartedEvent simulationStartedEvent = _eventAggregator.GetEvent<SimulationStartedEvent>();
            if (_subscriptionToken != null)
            {
                buyOrderMadeEvent.Unsubscribe(_subscriptionToken);
                sellOrderMadeEvent.Unsubscribe(_subscriptionToken);
                tickElapsedEvent.Unsubscribe(_subscriptionToken);
                simulationStartedEvent.Unsubscribe(_subscriptionToken);
            }

            _subscriptionToken = buyOrderMadeEvent.Subscribe(OnBuyOrderMade, ThreadOption.UIThread, false);
            _subscriptionToken = sellOrderMadeEvent.Subscribe(OnSellOrderMade, ThreadOption.UIThread, false);
            _subscriptionToken = tickElapsedEvent.Subscribe(OnTickElapsed, ThreadOption.UIThread, false);
            _subscriptionToken = simulationStartedEvent.Subscribe(OnSimulationStarted, ThreadOption.UIThread, false);

        }

        #region Handling Events

        private void OnBuyOrderMade(OrderBase order)
        {
            this.CurrentAccount.CurrentSession.ActiveOrders.Add(order);
        }

        private void OnSellOrderMade(OrderBase order)
        {
            this.CurrentAccount.CurrentSession.ActiveOrders.Add(order);
        }

        private void OnTickElapsed(Tick tick)
        {
            foreach (OrderBase order in this.CurrentAccount.CurrentSession.ActiveOrders)
            {
                decimal offset = tick.CurrentPrice - order.LastChangePrice;

                if (order.IsClosed)
                    continue;
                switch (order.Type)
                {
                    case OrderType.BuyOrder:
                        {
                            order.Profit += offset * order.Volume;
                            this.CurrentAccount.Balance.Add(offset * order.Volume);
                            order.LastChangePrice = tick.CurrentPrice;

                            break;
                        }
                    case OrderType.SellOrder:
                        {
                            order.Profit -= offset * order.Volume;
                            this.CurrentAccount.Balance.Subtract(offset * order.Volume);
                            order.LastChangePrice = tick.CurrentPrice;

                            break;
                        }
                    case OrderType.PendingOrder:
                        break;
                    case OrderType.Order:
                        break;
                    default:
                        break;
                }
            }
        }

        private void OnSimulationStarted(Simulation simulation)
        {
            // activate the account
            this.CurrentAccount = simulation.Account;
            
            this.TickFrequency = simulation.TickFrequency;
            this.Mode = simulation.SimulationMode;

            this.DataContext = CurrentAccount;
        }

        #endregion

        private void OnOrderClosed(object sender, RoutedEventArgs e)
        {
            OrderBase closingOrder = listActiveOrders.SelectedItem as OrderBase;
            if (closingOrder == null)
                return;
            closingOrder.IsClosed = true;
            closingOrder.ClosingPrice = closingOrder.LastChangePrice;

            this.CurrentAccount.CurrentSession.ActiveOrders.Remove(closingOrder);
            this.CurrentAccount.CurrentSession.ClosedOrders.Add(closingOrder);
        }

        #region Fields & Properties

        private Account _currentAccout;
        public Account CurrentAccount
        {
            get
            {
                return _currentAccout;
            }
            set
            {
                if (_currentAccout != value)
                {
                    _currentAccout = value;
                    RaisePropertyChanged("CurrentAccount");
                    if (_currentAccout != null)
                    {
                        this.IsReady = true;
                        RaisePropertyChanged("IsReady");
                    }
                    else
                    {
                        this.IsReady = false;
                        RaisePropertyChanged("IsReady");
                    }
                }
            }
        }

        private CurrencyEnum _currencyPair;
        public CurrencyEnum CurrencyPair
        {
            get { return _currencyPair; }
            set
            {
                _currencyPair = value; 
                RaisePropertyChanged("CurrencyPair");
            }
        }

        private TickFrequency _tickFrequency;
        public TickFrequency TickFrequency
        {
            get { return _tickFrequency; }
            set
            {
                _tickFrequency = value;
                RaisePropertyChanged("TickFrequency");
            }
        }

        private SimulationMode _mode;
        public SimulationMode Mode
        {
            get { return _mode; }
            set
            {
                _mode = value;
                RaisePropertyChanged("Mode");
            }
        }

        public IEventAggregator _eventAggregator { get; set; }
        public SubscriptionToken _subscriptionToken { get; set; }

        #endregion
        
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region ITileViewItem Members

        public string Title
        {
            get;
            set;
        }
        public object Icon { get; set; }

        private bool _isReady;
        public bool IsReady
        {
            get { return _isReady; }
            set
            {
                _isReady = value;
                RaisePropertyChanged("IsReady");
            }
        }

        #endregion
    }
}
